package com.cooper.beautyseesee;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import com.actionbarsherlock.view.MenuItem;
import com.cooper.android.comm.FileUtils;
import com.cooper.beautyseesee.data.BeautySource;
import com.cooper.beautyseesee.data.BeautyType;
import com.cooper.scraper.DownloadCancelled;
import com.cooper.scraper.DownloadException;
import com.cooper.scraper.DownloadParams;
import com.cooper.scraper.HttpDownload;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.app.SlidingFragmentActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;

public class MainActivity extends SlidingFragmentActivity {

	public static final String INFO_URL = "http://beauty-seesee-db.googlecode.com/svn/beauty/info.xml";

	private Fragment mContent;
	private ArrayList<BeautyType> beautyTypes;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setTitle(R.string.app_name);

		setBehindContentView(R.layout.menu_frame);

		setContentView(R.layout.content_frame);
		// customize the SlidingMenu
		SlidingMenu sm = getSlidingMenu();
		sm.setShadowWidthRes(R.dimen.shadow_width);
		sm.setShadowDrawable(R.drawable.shadow);
		sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
		sm.setFadeDegree(0.35f);
		sm.setBehindWidth(300);

		if (savedInstanceState != null) {
			mContent = getSupportFragmentManager().getFragment(
					savedInstanceState, "mContent");
			beautyTypes = savedInstanceState
					.getParcelableArrayList("BEAUTY_TYPES");
		}

		showBeautyTypeList();

		if (beautyTypes != null) {

			if (savedInstanceState.getBoolean("SLIDING_MENU_SHOWING", false)
					&& !sm.isMenuShowing()) {
				toggleOnStart = true;
			}
		}

	}

	private boolean toggleOnStart = false;

	@Override
	protected void onResume() {
		super.onResume();
		if (toggleOnStart)
			getSlidingMenu().toggle();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			toggle();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	private boolean stateSaved = false;

	@Override
	public void onSaveInstanceState(Bundle outState) {
		stateSaved = true;
		super.onSaveInstanceState(outState);

		if (mContent != null)
			getSupportFragmentManager().putFragment(outState, "mContent",
					mContent);
		if (beautyTypes != null)
			outState.putParcelableArrayList("BEAUTY_TYPES", beautyTypes);
		if (getSlidingMenu() != null)
			outState.putBoolean("SLIDING_MENU_SHOWING", getSlidingMenu()
					.isMenuShowing());
	}

	public void contentWaiting() {
		findViewById(R.id.waiting_content).setVisibility(View.VISIBLE);
	}

	public void contentFinish() {
		findViewById(R.id.waiting_content).setVisibility(View.GONE);
	}

	private void showBeautyTypeList() {

		if (stateSaved) {
			return;
		}

		if (beautyTypes == null) {

			contentWaiting();
			getSupportActionBar().setDisplayHomeAsUpEnabled(false);
			getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
			new BeautyTypesDownTask().execute();
			Log.d("MainActivity", "BeautyTypesDownTask().execute()");
		} else {
			if (mContent == null)
				mContent = BeautyListFragment.newInstance(beautyTypes.get(0));

			getSlidingMenu()
					.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);

			getSupportActionBar().setDisplayHomeAsUpEnabled(true);

			getSupportFragmentManager().beginTransaction()
					.replace(R.id.content_frame, mContent).commit();

			getSupportFragmentManager()
					.beginTransaction()
					.replace(R.id.menu_frame,
							BeautyTypeFragment.newInstance(beautyTypes))
					.commit();

			// customize the SlidingMenu
			getSlidingMenu()
					.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);

			findViewById(R.id.waiting_content).setVisibility(View.GONE);

		}
	}

	public void switchBeautyListFragment(BeautyType type) {
		mContent = BeautyListFragment.newInstance(type);
		getSupportFragmentManager().beginTransaction()
				.replace(R.id.content_frame, mContent).commit();
		getSlidingMenu().showContent();
	}

	public class BeautyTypesDownTask extends
			AsyncTask<String, Integer, ArrayList<BeautyType>> implements
			DownloadCancelled {

		private static final String DB_TAG = "database";
		private static final String DB_INDEX_TAG = "index";

		private static final String LIST_TYPE_TAG = "type";
		private static final String LIST_URI_TAG = "scaper";

		private static final String IMG_CHCHE_DIR = ".cooper_soft/beautyseesee/imgchche/";

		@Override
		protected void onPostExecute(ArrayList<BeautyType> result) {

			Log.d("BeautyListDownTask", "onPostExecute:" + result);
			if (!isCancelled()) {
				if (result != null) {
					BeautyType randomType = new BeautyType();
					randomType.setName(getResources().getString(
							R.string.app_name));
					randomType.setSourceUris(new ArrayList<BeautySource>());
					for (BeautyType type : result) {
						randomType.getSourceUris().addAll(type.getSourceUris());
					}
					result.add(0, randomType);
					beautyTypes = result;
					showBeautyTypeList();
				} else {
					// TODO Toast error
				}
			}
		}

		private void checkDownTypeBackground(HttpDownload httpDownload,
				List<BeautyType> types) throws DownloadException {

			File cachePath = new File(Environment.getExternalStorageDirectory()
					.toString() + "/" + IMG_CHCHE_DIR + "/");
			if (!cachePath.exists() || !cachePath.isDirectory()) {
				cachePath.mkdirs();
			}

			for (BeautyType type : types) {

				if (this.isCancelled())
					return;
				File cacheImgFile = new File(Environment
						.getExternalStorageDirectory().toString()
						+ "/"
						+ IMG_CHCHE_DIR
						+ "/"
						+ FileUtils.stringToFileName(type.getBackgroundUri()));
				if (!cacheImgFile.exists()) {
					httpDownload.downloadFile(type.getBackgroundUri(),
							cacheImgFile);
				}
				type.setBackgroundUri(cacheImgFile.getPath());
			}
		}

		private ArrayList<BeautyType> doBeautyTypeList(
				HttpDownload httpDownload, String url)
				throws DownloadException, XmlPullParserException, IOException {

			ArrayList<BeautyType> result = new ArrayList<BeautyType>();

			String page = httpDownload.downloadPage(url, false);
			if (isCancelled() || page == null || "".equals(page)) {
				return null;
			}

			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(true);
			XmlPullParser xpp = factory.newPullParser();
			xpp.setInput(new StringReader(page));
			int eventType = xpp.getEventType();
			boolean inUriTag = false;
			BeautyType currBeautyType = null;
			BeautySource currBeautySource = null;
			Integer inputKey = null;

			while (eventType != XmlPullParser.END_DOCUMENT) {

				if (eventType == XmlPullParser.START_TAG) {
					if (LIST_TYPE_TAG.equals(xpp.getName())) {
						currBeautyType = new BeautyType();
						currBeautyType.setBackgroundUri(xpp.getAttributeValue(
								null, "background"));
						currBeautyType.setName(xpp.getAttributeValue(null,
								"name"));
						currBeautyType
								.setSourceUris(new ArrayList<BeautySource>());
					} else if (LIST_URI_TAG.equals(xpp.getName())) {
						currBeautySource = new BeautySource(

						Integer.parseInt(xpp.getAttributeValue(null, "id")));

						// TODO scrape
						// currBeautySource.setScrapeId(Integer.parseInt(xpp.getAttributeValue(null,
						// "scrape")));
						inUriTag = true;
					} else if (inUriTag && "key".equals(xpp.getName())) {
						inputKey = Integer.parseInt(xpp.getAttributeValue(null,
								"input"));
					}

				} else if (eventType == XmlPullParser.TEXT) {
					if ((inputKey != null) && (xpp.getText() != null)
							&& !"".equals(xpp.getText())) {
						currBeautySource.putKeyWord(inputKey, xpp.getText());
					}

				} else if (eventType == XmlPullParser.END_TAG) {
					if (LIST_TYPE_TAG.equals(xpp.getName())) {
						result.add(currBeautyType);
					} else if (LIST_URI_TAG.equals(xpp.getName())) {
						currBeautyType.getSourceUris().add(currBeautySource);
						inUriTag = false;
					} else if (inUriTag && "key".equals(xpp.getName())) {
						inputKey = null;
					}
				}
				eventType = xpp.next();
			}

			return result;

		}

		@Override
		protected ArrayList<BeautyType> doInBackground(String... params) {
			HttpDownload httpDownload = new HttpDownload(new DownloadParams(
					this));

			try {
				String infoPage = httpDownload.downloadPage(INFO_URL, false);

				if (isCancelled() || infoPage == null || "".equals(infoPage)) {
					return null;
				}
				XmlPullParserFactory factory = XmlPullParserFactory
						.newInstance();
				factory.setNamespaceAware(true);
				XmlPullParser xpp = factory.newPullParser();
				xpp.setInput(new StringReader(infoPage));
				int eventType = xpp.getEventType();
				boolean inDBTag = false;
				boolean inDBIndexTag = false;
				String listIndexUri = null;

				while (eventType != XmlPullParser.END_DOCUMENT) {

					if (eventType == XmlPullParser.START_TAG) {
						if (DB_TAG.equals(xpp.getName())) {
							inDBTag = true;
						} else if (inDBTag
								&& DB_INDEX_TAG.equals(xpp.getName())) {
							inDBIndexTag = true;
						}

					} else if (eventType == XmlPullParser.TEXT) {
						if (inDBIndexTag) {
							listIndexUri = xpp.getText();
						}

					} else if (eventType == XmlPullParser.END_TAG) {
						if (DB_TAG.equals(xpp.getName())) {
							inDBTag = false;
						} else if (inDBTag
								&& DB_INDEX_TAG.equals(xpp.getName())) {
							inDBIndexTag = false;
						}
					}

					// TODO market check mode
					// TODO autoupdate
					// TODO scrape update
					eventType = xpp.next();
				}

				Log.d("BeautyListDownTask", "info.xml complete:" + listIndexUri);
				if (listIndexUri != null) {
					ArrayList<BeautyType> result = doBeautyTypeList(
							httpDownload, listIndexUri.trim());
					if (result != null && !result.isEmpty()) {
						checkDownTypeBackground(httpDownload, result);
						return result;
					}
				}
			} catch (Exception e) {
				Log.e("BeautyListDownTask", e.getMessage(), e);
			}
			return null;
		}

	}

}
